<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Supporting Repository Operations on Logical Models</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<h1>Supporting Repository Operations on Logical Models</h1>
<p>The purpose of this document is to present details of the solutions for the 
  repository operation scenarios presented in <a href="logical-support.html">Enabling 
  Logical Model Integration in the Eclipse Platform</a>.</p>
<h2>Logical to Physical Mappings</h2>
<p>A well integrated development environment should support 3rd party operations, 
  such as repository provider operations, on UI model elements that map to the 
  underlying Platform Resource model. Eclipse currently does support this for 
  cases where there is a one-to-one mapping from a model element to a resource. 
  However, to get full integration, one-to-many, and many-to-one should also be 
  supported. </p>
<h3>Performing Resource Based Operations on Logical Models</h3>
<p>In order for resource based operations, such as repository operations, to be 
  performed on logical models, a means to communicate resources that constitute 
  the model elements is required. This is the purpose of the <code>ResourceMapping</code> 
  API introduced in Eclipse 3.1 M5. This mapping supports a &quot;one model element 
  to many resource&quot; mapping. The specifics of this support is outlined <a href="http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/platform-vcm-home/docs/online/team3.1/logical-physical-mappings.html">here</a>.</p>
<p>The following points summarize how <code>ResourceMappings</code> are used to 
  communicate the resources of a model element to a repository provider.</p>
<ol>
  <li>Repository providers contribute menu operations to model elements through 
    the Platform adaptable mechanism. The menu items will appear on any elements 
    that adapt to <code>ResourceMapping</code>.</li>
  <li>When the user performs a repository operation on a model element, the contributed 
    operation is handed the <code>ResourceMappings</code> obtained from the model 
    elements.</li>
  <li> What happens next depends on what operation was chosen. For instance, a 
    check-in (or commit) operation can use the resource mapping to check-in the 
    appropriate files. Other operations can similarly be performed on the resources 
    that constitute the model element.</li>
  <li>In some cases, the remote state of the model may contain additional resources. 
    The <code>ResourceMappingContext</code> API is a way to allow the repository 
    provider to communicate to the model provider the means to determine the remote 
    state of the model so that all relevant resources can be included in the operation. 
    For instance, an html file model may include the images shown on a page. If 
    additional images are added to the remote state, operations such as update 
    or merge would want to include the new images.</li>
</ol>
<p>Once an operation is triggered, some operations may need to obtain additional 
  input from the user or show operation feedback. Ideally, the information shown 
  in dialogs or other views used to obtain information from or show information 
  to the user should be consistent with the model from which the operation was 
  launched or, in the very least, provide a link between the resources being operated 
  on and the originating model elements. The following list outlines some of the 
  different scenarios where this issue may occur:</p>
<ul>
  <li>It may be desirable to provide the ability to exclude some of the model 
    elements from the operation due to resource state (e.g. may want to prompt 
    when replacing model elements that contain dirty files). When a single model 
    element maps to one or more resources, this is straight forward. However, 
    if many model elements are contained in the same file, the model elements 
    may need to be included/excluded as a group. This is further complicated by 
    the fact that all affected model elements may not be contained in the input 
    to the operation. This is covered in the &quot;Handling Many-to-One Mappings&quot; 
    section.</li>
  <li>Repository operations often involve the merging of remote changes with local 
    changes. This involves fairly complicated interactions between the model and 
    the repository. This discussed in more detail in the next section.</li>
</ul>
<h3>Merging Logical Model Changes</h3>
<p>One of the more complicated scenarios involving repository providers is when 
  remote changes need to be merged with local changes. Here are the merge cases:</p>
<ul>
  <li>When a merge is required, a headless merge may be possible at the file level 
    which means that it could be performed by the repository provider without 
    the involvement of the model (i.e. no knowledge of model semantics is needed). 
  </li>
  <li>It is also possible that a headless merge is not possible at the file level 
    but is possible at the model level (i.e. the knowledge of the models semantics 
    makes a headless merge possible). </li>
  <li>If a headless merge is not possible, the user will need to perform a manual 
    merge. </li>
</ul>
<p>The interesting cases are the last two (i.e. merge involving model semantics 
  and manual merge).</p>
<p>There are several complications that must be considered when formulating a 
  solution:</p>
<ul>
  <li>The elements being merged may come from different model tooling and hence 
    are parts of different models. This is currently unlikely since there are 
    few generic views showing elements from different models but may become more 
    likely in the future as more generic views surface.</li>
  <li>At the lowest level, merges happen on files. If the multiple model elements 
    are contained in a single file, it is highly possible that additional model 
    elements may be affected by the merge. This means that the scope of the merge 
    may be greater than what was originally indicated by the user when they launched 
    the operation that triggered the merge.</li>
  <li>The model elements being merged may be contained by higher level models 
    or may involve files that are contained by other models. The challenge here 
    is to display the merge in a way that makes this obvious to the user and allows 
    them to decide which merge mechanism is more appropriate. In the case of layered 
    models, it may be appropriate to choose the highest level model as the default 
    merge mechanism.</li>
  <li>In order for model tooling to display the merge in a form that is consistent 
    with the model, access to the ancestor and remote state for files needs to 
    be accessible.This would require API provided by the repository provider.</li>
  <li>The merge happens as part of a repository operation. When the merge is complete, 
    the repository operation may then need to perform additional portions of the 
    operation (e.g. modify the synchronization state of local resources). This 
    is complicated by the fact that the merge may have been completed on a subset 
    of the elements included in the operation (and the other elements skipped).</li>
</ul>
<p>A solution for presenting model based merges could take several forms:</p>
<ul>
  <li>A separate dialog or wizard page for each model type involved in the merge. 
    This is OK if the models are disjoint but may be a problem if there is overlap.</li>
  <li>A single page that displays all the model elements being merged. Selecting 
    a model element will populate other portions of the page appropriately. The 
    advantage is that the user will see the entire scope of the operation at once. 
    However, it will still be difficult to highlight model overlap. This will 
    also require a more standardized presentation which may be more restrictive.</li>
</ul>
<p>The second approach is already supported by the compare framework and feels 
  like a better approach. Hence, we will concentrate on that solution for the 
  time being. Here is what this solution may involve:</p>
<ul>
  <li>A mechanism is provided for obtaining a model specific <code>DiffNode</code> 
    (Compare component API) for each <code>ResourceMapping</code> that is being 
    operated on. This would allow the merge operation to convert the selection 
    into a form that could appear in a merge viewer. Each type of <code>DiffNode</code> 
    may have model specific operations that should appear in the context menu 
    or toolbar. 
    <ul>
      <li>The mechanism for creating the <code>DiffNodes</code> will need access 
        to the remote and ancestor (or base) state of the model.</li>
      <li>Need to be able to include additional <code>DiffNodes</code> from a 
        model for the case where one of the selected elements is contained in 
        a file with other model elements.</li>
      <li>Ideally, <code>DiffNodes</code> could be obtained from other models 
        that are interested in the resources being merged.This becomes more complicated 
        as there may be relationships between multiple models (i.e. one may be 
        built on top of another) and you would want the display of the <code>DiffNodes</code> 
        to reflect this.</li>
    </ul>
  </li>
  <li>A merge viewer that can contain <code>DiffNodes</code> from one or more 
    models. Operations appropriate to a selected node should appear in the context 
    menu and toolbar. Also, selecting a node should update the other portions 
    of the merge viewer (structured comparison and content comparison panes). 
    Expansion of <code>DiffNodes</code> should also be supported.</li>
</ul>
<p>The key here is that the model is in complete control of the merge of its model 
  elements (i.e. the user may not even need to be aware of the underlying files). 
</p>
<h3>Handling Many-to-One Mappings</h3>
<p>Another interesting case involves the case where a single Platform resource 
  contains several model elements. If the user selects a single model element 
  and performs a repository operation on it, it will affect other model elements 
  as well. This will be confusing to the user if they see other model elements 
  being affected by an operation on one element. Here are some the scenarios involving 
  this case:</p>
<ul>
  <li>The user wants to tag (i.e. label or version) a specific model element but 
    doing so will tag all the elements contained in the same file. It may be enough 
    to warn the user that more than one element will be tagged but ideally, the 
    user could be shown all the elements that will be tagged.</li>
  <li>The user wants to merge a model element. If the model provides the merge 
    viewer, than this may be possible without involving the other elements. However, 
    the repository provider would need to be able to differentiate this from a 
    full file merge since the action taken upon merge completion may differ. For 
    some operations that start with a merge, such as check-in, all the elements 
    in the file would need to be merged.</li>
  <li>The user wants to replace a model element with the contents from the repository. 
    The operation doesn't need a merge since local contents are being replaced. 
    However, like a merge, it may be possible for the model to perform the replace 
    on the specific element given the contents of the two files. Without this 
    capability, the user would need to be informed that additional elements will 
    be included in the operation.</li>
  <li>Goto action on a file marker (https://bugs.eclipse.org/bugs/show_bug.cgi?id=87288). 
    If many elements are contained in a single file, it is possible that multiple 
    editors may be open on the same file. A mechanism to pcik the proper editor 
    is needed.</li>
</ul>
<p>Possible solutions to this problem are:</p>
<ul>
  <li>Provide a hint on the resource mapping or traversals that the file is not 
    wholly contained by the model element. This would at least allow the repository 
    provider to warn the user that the operation will affect additional elements. 
    If the traversal also included the range within a file, this could be used 
    for linking operation such as the one involving the linking of markers to 
    editors mentioned above. This could also be used to perform replacement of 
    file sections but would require the the ability to obtain the corresponding 
    range from the remote contents as well.</li>
  <li>Provide a means of obtaining the additional model elements that will be 
    affected. This will allow the repository provider to display all the elements 
    that will be affected but requires additional API.</li>
</ul>
<p>This problem has some overlap with the physical to logical problem which is 
  covered in the &quot;Physical to Logical&quot; section, in the sense that, if 
  a mechanism existed for finding all model elements from any model that are contained 
  within a resource, this could be used as the API for the second point mentioned 
  above.</p>
<h3>Decorations</h3>
<p>Decorating logical elements based on their resource mapping is problematic 
  is some cases. The most interesting case is decorating elements to indicate 
  that they have changed locally with respect to the repository. There are two 
  aspects of this that are problematic:</p>
<ol>
  <li>When a file contains many logical elements, only a few may be dirty when 
    the file is dirty. However, they will all appear dirty if the file dirty state 
    is used to determine the decoration. This can be overcome by allowing the 
    model provider to determine model element dirty state by comparing the modified 
    local file contents with that of the unmodified contents from the repository. 
    Unfortunately, this requires that either the unmodified contents are cached 
    or fetched from the server.</li>
  <li>When elements are shown in a tree, the resource mapping of a parent may 
    not contain all the resource mappings of its children. This is due to the 
    use of content providers in tree views that determine what the children of 
    an element are in the tree. The only solution to this is to use model elements 
    that contain the logic of determining their children and use a simple content 
    provider that obtains the children from the model element. The problem with 
    this approach is that it leads to model wrapping when alternate views are 
    used (which is something the content provider API was supposed to solve).</li>
</ol>
<h2>&nbsp;</h2>
<h2>Status</h2>
<p>Here is the status of this work as of 3.1 M5</p>
<ul>
  <li><a href="logical-physical-mappings.html">ResourceMapping/ResourceMappingContext</a>: 
    Initial cut is available in 3.1 M5 and will be in 3.1 as provisional API.</li>
  <li>Merge Support: Although work has not begun, this area is well bounded and 
    well understood. </li>
</ul>
<h2>Open Issues</h2>
<p>Here are the list of open issues:</p>
<ul>
  <li><strong>Transaction support</strong>: Some repository may have transaction 
    support. It is unclear how this fits in with logical model support.</li>
</ul>
<p>&nbsp;</p>
</body>
</html>
